import React, { ReactElement } from 'react';
import {
  getFreeDiskStorageSync,
  getTotalDiskCapacitySync
} from 'react-native-device-info';

import { Dispatch, State, Capacity } from './types';
import { DOWNLOAD_MANAGE_TYPE } from './constant';
import navigator from '../../util/navigator';
import systemUtil from '../../util/native/systemUtil';
import { modalOpen, modalClose } from '../../util/global';
import PortraitAlert from '../../components/Alert/PortraitAlert';
import { APP_RED } from '../../constant/color';
import { isIOS } from '../../constant';
import netInfo from '../../common/netInfo';
import { getUserInfo } from '../../store/user';
import { SortedDownloadVideoTasks } from '../../util/videoDownload/types';
import {
  emptySortedDownloadVideoTasks,
  getOnlyWifiDownload,
  getSortedStoreVideoTask,
  getSortedStoreVideoTaskList
} from '../../util/videoDownload/videoDownloadStore';
import {
  continueDownload,
  deleteDownloadByParentId,
  deleteDownloadVideoTask,
  getCurrentDownloadVideoTask,
  pauseDownloadByParentId,
  pauseDownloadVideoTask,
  startDownloadByParentId
} from '../../util/videoDownload/videoDownloadManage';

let dispatch: Dispatch;
let state: State;

export default (d: Dispatch, s: State): void => {
  dispatch = d;
  state = s;
};

export const setPageType = (value: DOWNLOAD_MANAGE_TYPE): void => {
  dispatch({ type: 'SET_PAGE_TYPE', value });
};

export const setEditStatus = (value: boolean): void => {
  dispatch({ type: 'SET_EDIT_STATUS', value });
};

export const setDownloadingList = (value: SortedDownloadVideoTasks[]): void => {
  dispatch({ type: 'SET_DOWNLOADING_LIST', value });
};

export const setFinishedList = (value: SortedDownloadVideoTasks[]): void => {
  dispatch({ type: 'SET_FINISHED_LIST', value });
};

export const setSelectedPIds = (value: number[]): void => {
  dispatch({ type: 'SET_SELECTED_PIDS', value });
};

export const setSelectedAllDownloading = (value: boolean): void => {
  dispatch({ type: 'SET_SELECTED_ALL_DOWNLOADING', value });
};

export const setCapacity = (value: Capacity): void => {
  dispatch({ type: 'SET_CAPACITY', value });
};

export const setCurrentDownload = (value: SortedDownloadVideoTasks): void => {
  dispatch({ type: 'SET_CURRENT_DOWNLOAD', value });
};

export const setNetSpeed = (value: number): void => {
  dispatch({ type: 'SET_NET_SPEED', value });
};

// 更新parent下载列表
export const updateList = (): void => {
  const downloadList = getSortedStoreVideoTaskList();
  const finishedList = downloadList.filter(
    (item): boolean => item.progress >= 1
  );
  const downloadingList = downloadList.filter(
    (item): boolean => item.progress < 1
  );
  setFinishedList(finishedList);
  setDownloadingList(downloadingList);
};

// 更新当前下载parent视频
export const updateCurrentDownload = (): void => {
  const currentDownload = getCurrentDownloadVideoTask();

  if (currentDownload) {
    const { parentId } = currentDownload;
    const currentDownloadSortedVideos = getSortedStoreVideoTask(parentId);
    setCurrentDownload(currentDownloadSortedVideos);
  } else {
    setCurrentDownload(emptySortedDownloadVideoTasks);
  }
};

// 字节转其他单位
export const calBytes = (value: number): string => {
  const kb = value / 1024;

  if (kb < 1024) {
    return `${kb.toFixed(0)}KB`;
  }

  const mb = kb / 1024;
  if (mb < 1024) {
    return `${mb.toFixed(1)}M`;
  }

  const gb = mb / 1024;
  return `${gb.toFixed(1)}G`;
};

// MB转其他单位
export const calFileSize = (value: number): string => {
  if (value < 1) {
    return `${(value * 1024).toFixed(0)}KB`;
  }
  if (value < 1024) {
    return `${value.toFixed(1)}M`;
  }
  return `${(value / 1024).toFixed(1)}G`;
};

// 更新空间
export const updateCapacity = (): void => {
  if (isIOS) {
    const availMemory = getFreeDiskStorageSync();
    const totalMemory = getTotalDiskCapacitySync();

    setCapacity({
      freeCapacity: calBytes(Number(availMemory)),
      totalCapacity: calBytes(Number(totalMemory))
    });
  } else {
    const { availMemory, totalMemory } = systemUtil.getMemoryInfo();

    setCapacity({
      freeCapacity: calFileSize(Number(availMemory)),
      totalCapacity: calFileSize(Number(totalMemory))
    });
  }
};

// 返回
export const backAction = (): void => {
  const { isEdit, type } = state;
  if (isEdit) {
    setEditStatus(false);
    return;
  }
  if (type !== DOWNLOAD_MANAGE_TYPE.All) {
    setPageType(DOWNLOAD_MANAGE_TYPE.All);
    return;
  }
  navigator.goBack();
};

// 查看正在缓存
export const checkDownloading = (): void => {
  setPageType(DOWNLOAD_MANAGE_TYPE.Ing);
};

// 网络环境提醒
export const netAlert = (): boolean => {
  const netType = netInfo.getNetType();
  const { userId } = getUserInfo();
  const onlyWifiDownload = getOnlyWifiDownload(userId);
  if (netType === '4g' && onlyWifiDownload) {
    modalOpen({
      Type: (): ReactElement => (
        <PortraitAlert
          title="下载设置"
          sureDesc="去设置"
          subTitle="当前设置仅在WI-FI网络下载，仍需下载请至【设置】开启"
          sureAction={(): void => {
            navigator.push('About');
            modalClose();
          }}
          cancelAction={modalClose}
          cancelDesc="我知道了"
        />
      ),
      needBack: true
    });
    return true;
  }
  return false;
};

// 选择下载条目
export const selectDownloadParent = (id: number): void => {
  const { selectedPIds } = state;
  const index = selectedPIds.findIndex((item): boolean => item === id);

  if (index === -1) {
    selectedPIds.push(id);
  } else {
    selectedPIds.splice(index, 1);
  }

  setSelectedPIds(selectedPIds);
};

// 全选
export const selectDownloadAll = (): void => {
  const { type, finishedList, downloadingList, currentDownload } = state;
  if (type === DOWNLOAD_MANAGE_TYPE.All) {
    const selectedPIds: number[] = [];
    finishedList.forEach((item): void => {
      selectedPIds.push(item.parentId);
    });
    if (currentDownload.parentId) {
      selectedPIds.push(currentDownload.parentId);
    }
    setSelectedPIds(selectedPIds);
    setSelectedAllDownloading(true);
  } else if (type === DOWNLOAD_MANAGE_TYPE.Ing) {
    setSelectedPIds(downloadingList.map((item): number => item.parentId));
  }
};

// 判断展示全选/取消
export const judgeIsShowSelectAllButton = (): boolean => {
  const {
    type,
    finishedList,
    downloadingList,
    selectedPIds,
    currentDownload,
    selectedAllDownloading
  } = state;
  if (type === DOWNLOAD_MANAGE_TYPE.All) {
    const noSelectedAllPIds = finishedList.some(
      (item): boolean => !selectedPIds.includes(item.parentId)
    );
    if (finishedList.length === 0 && !currentDownload.parentId) return true;
    if (currentDownload.parentId) {
      return noSelectedAllPIds || !selectedAllDownloading;
    }
    return noSelectedAllPIds;
  }

  if (type === DOWNLOAD_MANAGE_TYPE.Ing) {
    if (downloadingList.length === 0) return true;
    return downloadingList.some(
      (item): boolean => !selectedPIds.includes(item.parentId)
    );
  }

  return true;
};

// 取消全选
export const unSelectDownloadAll = (): void => {
  setSelectedPIds([]);
  setSelectedAllDownloading(false);
};

// 删除勾选的下载parent
export const deleteDownload = (): void => {
  const { selectedPIds, selectedAllDownloading, downloadingList } = state;
  if (selectedAllDownloading) {
    downloadingList.forEach((item): void => {
      deleteDownloadByParentId(item.parentId);
    });
  }
  selectedPIds.forEach((item): void => {
    deleteDownloadByParentId(item);
  });

  setTimeout((): void => {
    updateList();
    updateCurrentDownload();
    updateCapacity();
  }, 100);

  setEditStatus(false);
};

// 删除提示
export const deleteDownloadAlert = (): void => {
  modalOpen({
    Type: (): React.ReactElement => (
      <PortraitAlert
        title="确认删除"
        sureDesc="删除"
        subTitle="确认删除已勾选的缓存视频吗？"
        sureDescStyle={{ color: APP_RED }}
        sureAction={(): void => {
          deleteDownload();
          modalClose();
        }}
        cancelDesc="取消"
        cancelAction={modalClose}
      />
    ),
    needBack: true
  });
};

// 对单独下载任务进行操作
export const controlSingleDownload = (parentId: number): void => {
  const { downloadingList, currentDownload } = state;

  // 是当前下载任务
  if (currentDownload.parentId === parentId) {
    const { isPaused, isFailed } = currentDownload;
    if (!isPaused && !isFailed) {
      pauseDownloadVideoTask();
      pauseDownloadByParentId(parentId);
      continueDownload();
    }
  } else {
    const download = downloadingList.find(
      (item): boolean => item.parentId === parentId
    );
    if (download) {
      const { isPaused, isFailed } = download;

      if (!isPaused && !isFailed) {
        pauseDownloadByParentId(parentId);
      } else {
        if (netAlert()) {
          return;
        }
        startDownloadByParentId(parentId);
        continueDownload();
      }
    }
  }
  updateList();
  updateCurrentDownload();
};
